package tau.dimes.visualization.applet.heatMap;

import processing.core.PApplet;
import tau.dimes.visualization.applet.Parameters;

/**
 * Represents a node in the heat map.
 */
class HeatMapNode
{
	private final PApplet applet;
	private final HeatMap heatMap;
	private final float x;
	private final float y;
	private final int[] hits;
	private float heat;

	/**
	 * Constructs a new HeatMapNode.
	 * @param applet A reference to the containing applet.
	 * @param heatMap A reference to the containing HeatMap.
	 * @param x Horizontal coordinate.
	 * @param y Vertical coordinate.
	 */
	HeatMapNode(PApplet applet, HeatMap heatMap, float x, float y)
	{
		this.applet = applet;
		this.heatMap = heatMap;
		this.x = x;
		this.y = y;
		this.hits = new int[heatMap.getTimeSlots() + 1];
	}

	/**
	 * Increments the heat value for a given time slot index by one.
	 * @param timeSlot Time slot index.
	 */
	public void incrementHeat(int timeSlot)
	{
		hits[timeSlot]++;
	}

	/**
	 * Gets the heat value for a given time slot index.
	 * @param timeSlot Time slot index.
	 * @return Heat value for the given time slot index.
	 */
	public int getHeat(int timeSlot)
	{
		return hits[timeSlot];
	}

	/**
	 * Calculates a dynamic heat value for given time slot and alpha value.
	 * @param timeSlot Time slot index.
	 * @param alpha Alpha value (see Clock class).
	 */
	void calcHeat(int timeSlot, float alpha)
	{
		heat = 0;
				
		int maxindex = timeSlot;
		int nextindex = timeSlot + 1;
		float diff = alpha;
		int startindex = PApplet.max(1, maxindex - Parameters.getWindow() + 1);

		for (int index = startindex; index <= maxindex; index++)
			heat += getHeat(index);

		heat += diff * getHeat(nextindex);

		if (startindex > 1)
			heat += (1 - diff) * getHeat(startindex - 1);

		heatMap.setMaxHeat(heat);
	}

	/**
	 * Draws the graphical representation of the node.
	 */
	void draw()
	{
		applet.noStroke();
		applet.ellipseMode(PApplet.RADIUS);
		float radius = (float)Math.sqrt(heat / heatMap.getMaxHeat()) * Parameters.maxCircleRadius();
		for (float i = radius; i > 0; i -= 1)
		{
			applet.fill(255, 0, 0, ((radius - i) / radius) * 255);
			applet.ellipse(x, y, i, i);
		}
	}
}